package com.cqyc.network.http

import com.cqyc.network.getid.GetMyInformationBox
import okhttp3.*
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException
import java.security.MessageDigest
import java.util.*


object HttpUtil {
    lateinit var api: Api

    fun init(apiUrl: String) {
        val logging = HttpLoggingInterceptor()
        logging.level = HttpLoggingInterceptor.Level.BODY

        val okHttpClient = OkHttpClient.Builder()
            .addInterceptor { encrypt(it) }//添加请求头
            .addInterceptor(RequestInterceptor())//添加请求加密
            .addInterceptor(RespLogInterceptor())//添加返回解密
//            .addInterceptor(logging)//添加输入日志
            .build()
        val retrofit = Retrofit.Builder()
            .baseUrl(apiUrl)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        api = retrofit.create(Api::class.java)
    }

    @Throws(IOException::class)
    private fun encrypt(chain: Interceptor.Chain): Response {
        var request: Request = chain.request()
        val body = request.body
        if (body !is FormBody) {
            return chain.proceed(request)
        }
        val paramMap = TreeMap<String, String>()
        for (i in 0 until body.size) {
            if (body.value(i).isNotBlank()) {
                paramMap[body.name(i)] = body.value(i)
            }
        }
        val builder: Request.Builder = request.newBuilder()
        builder.addHeader("Authorization", GetMyInformationBox.getToken())
        builder.addHeader("source", GetMyInformationBox.getSource())
        val nonceStr: String = generatingRandomString()
        builder.addHeader("noncestr", nonceStr)
        val timestamp = (System.currentTimeMillis() / 1000).toString()
        builder.addHeader("timestamp" ,timestamp)
        val appVersion = GetMyInformationBox.getVersion()
        builder.addHeader("appVersion" ,appVersion)
        //TOD
        request = builder.post(getFormBody(paramMap ,nonceStr , appVersion ,timestamp)).build()
        return chain.proceed(request)
    }

    private fun getFormBody(paramMap: TreeMap<String, String> , nonceStr:String ,appVersion:String , timestamp:String): RequestBody {
        val builder = FormBody.Builder()
        paramMap["platform"] = "2"
        paramMap["appVersion"] = appVersion
        if (paramMap.isNotEmpty()){
              paramMap.forEach {
                 builder.add(it.key, it.value)
              }
        }
        builder.add("signature" , sign(paramMap, nonceStr, appVersion, timestamp))
        return builder.build()
    }

    private fun sign(
        paramsMap: TreeMap<String, String>,
        nonceStr: String,
        appVersion: String,
        timestamp: String
    ): String {
        val secret = "F_kmc*J@zmj1dAu^"
        val query = paramsMap.map { (k, v) ->
            "$k=$v"
        }.reduce { p1, p2 -> "$p1&$p2" }
        return md5("$query$secret$appVersion$nonceStr$timestamp")
    }

    private fun generatingRandomString(): String {
        var randomCode = ""
        val model = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"
        val m = model.toCharArray()
        for (j in 0..5) {
            val c = m[(Math.random() * 52).toInt()]
            randomCode += c
        }
        return randomCode
    }

    private fun md5(content: String): String {
        val hash = MessageDigest.getInstance("MD5").digest(content.toByteArray())
        val hex = StringBuilder(hash.size * 2)
        for (b in hash) {
            var str = Integer.toHexString(b.toInt())
            if (b < 0x10) {
                str = "0$str"
            }
            hex.append(str.substring(str.length - 2))
        }
        return hex.toString()
    }
}